//
//  ARDistanceViewController.swift
//  ScarnKing
//
//  Created by ninebot on 2025/7/22.
//

import UIKit
import ARKit
import SceneKit

class ARDistanceViewController: UIViewController, ARSCNViewDelegate {
    
    private var arView: ARSCNView!
    private var distanceLabel: UILabel!
    private var instructionLabel: UILabel!
    private var resetButton: UIButton!
    private var backButton: UIButton!
    
    private var startPoint: SCNVector3?
    private var endPoint: SCNVector3?
    private var distanceNode: SCNNode?
    private var lineNode: SCNNode?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupARView()
        setupUI()
        setupARSession()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 隐藏导航栏和底部导航栏
        navigationController?.setNavigationBarHidden(true, animated: false)
        navigationController?.tabBarController?.tabBar.isHidden = true
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 显示导航栏和底部导航栏
        navigationController?.setNavigationBarHidden(false, animated: false)
        navigationController?.tabBarController?.tabBar.isHidden = false
        arView.session.pause()
    }
    
    private func setupARView() {
        arView = ARSCNView(frame: view.bounds)
        arView.delegate = self
        arView.showsStatistics = false
        arView.autoenablesDefaultLighting = true
        arView.backgroundColor = .black
        view.addSubview(arView)
        
        // 添加点击手势
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
        arView.addGestureRecognizer(tapGesture)
    }
    
    private func setupUI() {
        // 距离显示标签
        distanceLabel = UILabel()
        distanceLabel.text = "点击屏幕选择起点"
        distanceLabel.textColor = .white
        distanceLabel.font = UIFont.boldSystemFont(ofSize: 18)
        distanceLabel.textAlignment = .center
        distanceLabel.backgroundColor = UIColor.black.withAlphaComponent(0.7)
        distanceLabel.layer.cornerRadius = 10
        distanceLabel.clipsToBounds = true
        distanceLabel.numberOfLines = 0
        view.addSubview(distanceLabel)
        
        // 操作说明标签
        instructionLabel = UILabel()
        instructionLabel.text = "点击屏幕选择起点和终点来测量距离"
        instructionLabel.textColor = .white
        instructionLabel.font = UIFont.systemFont(ofSize: 14)
        instructionLabel.textAlignment = .center
        instructionLabel.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        instructionLabel.layer.cornerRadius = 8
        instructionLabel.clipsToBounds = true
        instructionLabel.numberOfLines = 0
        view.addSubview(instructionLabel)
        
        // 重置按钮
        resetButton = UIButton(type: .system)
        resetButton.setTitle("重置", for: .normal)
        resetButton.setTitleColor(.white, for: .normal)
        resetButton.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.8)
        resetButton.layer.cornerRadius = 20
        resetButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
        resetButton.addTarget(self, action: #selector(resetMeasurement), for: .touchUpInside)
        view.addSubview(resetButton)
        
        // 返回按钮
        backButton = UIButton(type: .system)
        backButton.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
        backButton.tintColor = .white
        backButton.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        backButton.layer.cornerRadius = 20
        backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
        view.addSubview(backButton)
        
        // 设置约束
        distanceLabel.translatesAutoresizingMaskIntoConstraints = false
        instructionLabel.translatesAutoresizingMaskIntoConstraints = false
        resetButton.translatesAutoresizingMaskIntoConstraints = false
        backButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            // 返回按钮
            backButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            backButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            backButton.widthAnchor.constraint(equalToConstant: 40),
            backButton.heightAnchor.constraint(equalToConstant: 40),
            
            // 重置按钮
            resetButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
            resetButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            resetButton.widthAnchor.constraint(equalToConstant: 100),
            resetButton.heightAnchor.constraint(equalToConstant: 40),
            
            // 说明标签
            instructionLabel.bottomAnchor.constraint(equalTo: resetButton.topAnchor, constant: -20),
            instructionLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            instructionLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            instructionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 40),
            
            // 距离标签
            distanceLabel.bottomAnchor.constraint(equalTo: instructionLabel.topAnchor, constant: -20),
            distanceLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            distanceLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            distanceLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 50)
        ])
    }
    
    private func setupARSession() {
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal, .vertical]
        arView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
    }
    
    @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
        let location = gesture.location(in: arView)
        
        // 执行射线检测
        let hitTestResults = arView.hitTest(location, types: [.featurePoint, .existingPlaneUsingExtent])
        
        guard let hitTestResult = hitTestResults.first else {
            showAlert(message: "无法检测到有效点，请尝试其他位置")
            return
        }
        
        let worldPosition = SCNVector3(
            hitTestResult.worldTransform.columns.3.x,
            hitTestResult.worldTransform.columns.3.y,
            hitTestResult.worldTransform.columns.3.z
        )
        
        if startPoint == nil {
            // 设置起点
            startPoint = worldPosition
            addPointNode(at: worldPosition, color: .green)
            distanceLabel.text = "起点已设置"
            instructionLabel.text = "起点已设置（绿色点）\n点击屏幕选择终点"
        } else if endPoint == nil {
            // 设置终点
            endPoint = worldPosition
            addPointNode(at: worldPosition, color: .red)
            drawLine(from: startPoint!, to: worldPosition)
            calculateAndDisplayDistance()
            instructionLabel.text = "测量完成，点击重置开始新的测量"
        }
    }
    
    private func addPointNode(at position: SCNVector3, color: UIColor) {
        let sphere = SCNSphere(radius: 0.01)
        sphere.firstMaterial?.diffuse.contents = color
        
        let node = SCNNode(geometry: sphere)
        node.position = position
        arView.scene.rootNode.addChildNode(node)
    }
    
    private func drawLine(from start: SCNVector3, to end: SCNVector3) {
        // 移除之前的线条
        lineNode?.removeFromParentNode()
        
        let line = SCNGeometry.line(from: start, to: end)
        line.firstMaterial?.diffuse.contents = UIColor.yellow
        line.firstMaterial?.isDoubleSided = true
        
        lineNode = SCNNode(geometry: line)
        arView.scene.rootNode.addChildNode(lineNode!)
    }
    
    private func calculateAndDisplayDistance() {
        guard let start = startPoint, let end = endPoint else { return }
        
        let distance = sqrt(
            pow(end.x - start.x, 2) +
            pow(end.y - start.y, 2) +
            pow(end.z - start.z, 2)
        )
        
        let distanceInMeters = distance
        let distanceInCentimeters = distanceInMeters * 100
        
        var distanceText = ""
        if distanceInMeters >= 1.0 {
            distanceText = String(format: "距离: %.2f 米", distanceInMeters)
        } else {
            distanceText = String(format: "距离: %.1f 厘米", distanceInCentimeters)
        }
        
        distanceLabel.text = distanceText
        instructionLabel.text = "起点: 绿色点\n终点: 红色点\n\(distanceText)"
        
        // 保存到历史记录
        HistoryRecordManager.shared.addARDistanceRecord(distance: distanceText)
    }
    
    @objc private func resetMeasurement() {
        // 清除所有节点
        arView.scene.rootNode.enumerateChildNodes { node, _ in
            node.removeFromParentNode()
        }
        
        // 重置状态
        startPoint = nil
        endPoint = nil
        distanceNode = nil
        lineNode = nil
        
        // 更新UI
        distanceLabel.text = "点击屏幕选择起点"
        instructionLabel.text = "点击屏幕选择起点和终点来测量距离"
    }
    
    @objc private func backButtonTapped() {
        navigationController?.popViewController(animated: true)
    }
    
    private func showAlert(message: String) {
        let alert = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .default))
        present(alert, animated: true)
    }
}

// MARK: - SCNGeometry Extension
extension SCNGeometry {
    static func line(from start: SCNVector3, to end: SCNVector3) -> SCNGeometry {
        let vertices: [SCNVector3] = [start, end]
        let data = Data(bytes: vertices, count: vertices.count * MemoryLayout<SCNVector3>.size)
        
        let source = SCNGeometrySource(data: data,
                                     semantic: .vertex,
                                     vectorCount: vertices.count,
                                     usesFloatComponents: true,
                                     componentsPerVector: 3,
                                     bytesPerComponent: MemoryLayout<Float>.size,
                                     dataOffset: 0,
                                     dataStride: MemoryLayout<SCNVector3>.size)
        
        let element = SCNGeometryElement(data: nil,
                                       primitiveType: .line,
                                       primitiveCount: 1,
                                       bytesPerIndex: 0)
        
        return SCNGeometry(sources: [source], elements: [element])
    }
} 